package com.enjoyor.soa.traffic.frame.configure;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import com.google.common.base.Predicate;
import com.google.common.collect.Lists;

import springfox.documentation.RequestHandler;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.Contact;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration("swagger2Config")
@EnableSwagger2
@PropertySource({ "classpath:swagger2.properties" })
public class Swagger2Config {

    @Value("${swagger2.sso.authorizeUri}")
    private String authorizeUri;

    @Value("${swagger2.auto.scan.basePackage}")
    private String basePackage;

    @Bean
    @RefreshScope
    public Docket docket() {
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select().apis(apis())
                .paths(PathSelectors.any()).build().securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }

    @PostConstruct
    private void init() {
        System.out.println(
                String.format("[swagger2Config-init] authorizeUri: %s, basePackage: %s", authorizeUri, basePackage));
    }

    @Bean
    @RefreshScope
    public Predicate<RequestHandler> apis() {
        return RequestHandlerSelectors.basePackage(basePackage);
    }

    @Bean
    @RefreshScope
    public ApiInfo apiInfo() {
        Contact contact = new Contact("Enjoyor SmartTraffic", "", "");
        return new ApiInfoBuilder().title("Enjoyor SmartTraffic RESTful API").contact(contact).version("1.0")
                .description("token获取地址: " + authorizeUri).build();
    }

    private List<ApiKey> securitySchemes() {
        List<ApiKey> apiKeys = new ArrayList<ApiKey>();
        apiKeys.add(new ApiKey("token", "Authorization", "header"));
        return apiKeys;
    }

    private List<SecurityContext> securityContexts() {
        return Lists.newArrayList(SecurityContext.builder().securityReferences(defaultAuth())
                .forPaths(PathSelectors.regex("^(?!api).*$")).build());
    }

    private List<SecurityReference> defaultAuth() {
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        return Lists.newArrayList(new SecurityReference("token", authorizationScopes));
    }

    @Override
    public String toString() {
        return String.format("[swagger2Config] authorizeUri: %s, basePackage: %s", authorizeUri, basePackage);
    }

}
